/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce for the following functions:
 *     adjustedImageSize
 *     adjustedQuantity
 *     validateEmailFormat
 * These functions are a rewrite of functions found in osCommerce in the php language.
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.elf.gwt.common.client.utils;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.elf.gwt.common.client.GWTCommerceCommonConstants;
import com.elf.gwt.common.client.model.CountryModel;
import com.elf.gwt.common.client.model.CurrencyModel;
import com.elf.gwt.common.client.model.ZoneModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasName;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.datepicker.client.DateBox;

/**
 * Container class for a general group of static functions.
 */
public class CommonUtils
{
	public static boolean testSSL = false;

	protected static final String DISCOUNT_PREFIX = "from ";
	
	public static DateTimeFormat dateFormat =  DateTimeFormat.getFormat("yyyy-MM-dd");
	public static DateTimeFormat dateTimeFormat =  DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss");
	public static DateTimeFormat timeFormat =  DateTimeFormat.getFormat("HH:mm:ss");
	public static DateTimeFormat smallTimeFormat =  DateTimeFormat.getFormat("mm:ss");
	public static DateTimeFormat yearFormat =  DateTimeFormat.getFormat("yyyy");
	public static DateTimeFormat yearMonthFormat =  DateTimeFormat.getFormat("yyyyMM");

	private CommonUtils()
	{
	}
	
	/**
	 * Returns the absolute path to the images folder.
	 * @return images folder
	 */
	public static String getImageDirectory()
	{
		return GWT.getModuleBaseURL() + "images/";
	}

	/**
	 * Returns the absolute path to the images folder.
	 * @return images folder
	 */
	public static String getImageCommonDirectory()
	{
		return GWT.getModuleBaseURL() + "images/common/";
	}
	
	/**
	 * Returns an html string that can be used to display the price of a product.
	 * @param currenciesModel
	 * @param productPrice
	 * @param discountPrice
	 * @param specialPrice
	 * @return an html string representing price.
	 */
	public static String productPriceDisplay (CurrencyModel currenciesModel, double productPrice, double discountPrice, double specialPrice)
	{
		String priceOut = "";
		productPrice = productPrice * currenciesModel.getValue();
		discountPrice = discountPrice * currenciesModel.getValue();
		specialPrice = specialPrice * currenciesModel.getValue();

		NumberFormat fmt = NumberFormat.getCurrencyFormat(currenciesModel.getCode());

		if (productPrice > discountPrice || productPrice > specialPrice)
		{
			if (discountPrice < specialPrice)
			{
				priceOut = "<span class=\"price\">" + DISCOUNT_PREFIX + fmt.format(discountPrice)+ "</span>";
			}
			else
			{
				priceOut = "<span class=\"oldprice\">" + fmt.format(productPrice) + " </span>" +
				"<span class=\"price\">" + fmt.format(specialPrice)+ "</span>";
			}
		}
		else
		{
			priceOut = "<span class=\"price\">" + fmt.format(productPrice)+ "</span>";
		}

		return priceOut;
	}

	public static String priceDisplay (CurrencyModel currenciesModel, double price)
	{
		String priceOut = "";
		price = price * currenciesModel.getValue();

		NumberFormat fmt = NumberFormat.getCurrencyFormat(currenciesModel.getCode());
		if (price < 0)
			priceOut = "<span class=\"negativeprice\">" + fmt.format(price)+ "</span>";
		else
			priceOut = "<span class=\"price\">" + fmt.format(price)+ "</span>";

		return priceOut;
	}

	/** 
	 * add in breakChar to str at len number of characters without a space.
	 * @param str
	 * @param len
	 * @param breakChar
	 * @return
	 */
	public static String breakString(String str, int len, char breakChar) {

		StringBuffer sb = new StringBuffer();

		int currLen = 0;
		char[] chars = str.toCharArray();
		for (int i = 0; i<chars.length; i++)
		{
			char chr = chars[i];
			if (chr == ' ') currLen = 0;
			sb.append(chr);
			currLen++;
			if (currLen > len)
			{
				sb.append(breakChar);
				sb.append(' ');
				currLen = 0;
			}
		}

		return sb.toString();
	}

	/**
	 * return the SSL URL for this application
	 * @return string that is the SSL url.
	 */
	public static String getSslUrl()
	{
		String url = GWT.getHostPageBaseURL();

		//Window.alert("GWT.isScript " + GWT.isScript());

		if(GWT.isScript()) //Web Mode
		{
			int index = url.indexOf("https");
			if (index < 0)
			{
				index = url.indexOf("http");
				if (index > -1)
					url = "https" + url.substring(4);
				else
					url = "https://" + url;
			}
		}

		url = url + "index.php";
		return url;
	}


	/**
	 * return tru if Hosted Mode or SSL URL
	 */
	public static boolean isSSL()
	{
		if (testSSL) return false;

		boolean bool = false;

		if(GWT.isScript()) //Web Mode
		{
			String url = GWT.getHostPageBaseURL();

			int index = url.indexOf("https");
			if (index > -1)
			{
				bool = true;
			}
		}
		else
			bool = true;

		return bool;
	}

	/**
	 * Return true if emailAddress is in the correct format.
	 * @param emailAddress
	 * @return
	 */
	public static boolean validateEmailFormat(String emailAddress)
	{		
		int len = emailAddress.length();
		if (emailAddress == null || len == 0)
			return false;
		else 
			return true;
		/*
		

		int atPos = emailAddress.indexOf("@");
		int dotPos = emailAddress.indexOf(".");

		if (atPos < 1)
			return false;
		else if (dotPos < 3)
			return false;
		else if ((dotPos - atPos) < 2)
			return false;

		int pos = emailAddress.lastIndexOf( '.', len - 1 ) + 1;
		int diff = len - pos;

		if (diff < 2 || diff > 4)
			return false;

		return true;
		*/
	}

	/**
	 * Adds a subtitle to a panel.
	 * @param handle
	 * @param panel
	 * @param title
	 */
	public static void addSubTitle(String handle, Panel panel, String title)
	{
		//panel.add(new InlineHTML("&nbsp;"));
		InlineLabel label = new InlineLabel(title);
		label.setStyleName(handle + "SubTitle");
		label.setWidth("100%");
		panel.add(label);
	}

	/**
	 * Add a input widget to a grid.
	 * @param handle
	 * @param i
	 * @param widget
	 * @param grid
	 * @param name
	 * @param label
	 * @param text
	 */
	public static void addGridWidget(String handle, int i, Widget widget, Grid grid, String name, String label, String text)
	{
		CellFormatter cf = grid.getCellFormatter();
		try {
			HasName hasName = (HasName)widget;
			hasName.setName(name);		
		}
		catch(Exception e){}
		grid.setHTML(i, 0, label);
		cf.setWordWrap(i, 0, false);
		grid.setWidget(i, 1, widget);
		grid.setText(i, 2, text);
		cf.setWidth(i, 2, "100%");
		cf.setWordWrap(i, 2, false);
		cf.setStyleName(i, 2, "WarningLabel");
		cf.addStyleName(i, 2, handle + "WarningLabel");
	}

	/**
	 * Update the state dropdown.
	 * @param country
	 * @param state
	 */
	public static void updateStateListBox(String country, String state, List<CountryModel> countryModels, ListBox stateListBox)
	{
		if (state == null) state = "";
		stateListBox.clear();
		Iterator<CountryModel> iter = countryModels.iterator();
		while(iter.hasNext())
		{
			CountryModel cmodel = iter.next();
			if (cmodel.getName().equals(country))
			{
				Iterator<ZoneModel> iter1 = cmodel.getZones().iterator();
				int i = 0;
				boolean found = false;
				while(iter1.hasNext())
				{
					ZoneModel zmodel = iter1.next();
					stateListBox.addItem(zmodel.getName(), zmodel.getCode());

					if (state.equals(zmodel.getCode()))
					{
						stateListBox.setItemSelected(i, true);
						found = true;
					}
					else
						stateListBox.setItemSelected(i, false);
					i++;
				}
				if (!found && cmodel.getZones().size() > 0)
					stateListBox.setItemSelected(0, true);

			}
		}
	}

	/**
	 * Get the Component jsonValue by handle
	 * @param jsonValue
	 * @param handle
	 * @return
	 */
	public static JSONValue getComponentValue(JSONValue jsonValue, String handle)
	{
		JSONValue returnValue = null;
		JSONObject jsonObject;
		if ((jsonObject = jsonValue.isObject()) != null)
		{
			returnValue = jsonObject.get(handle);
		}
		return returnValue;
	}
	
	public static Set<String> getComponentHandles(JSONValue jsonValue)
	{
		Set<String> returnValue = null;
		if (jsonValue != null)
		{
			JSONObject jsonObject;
			if ((jsonObject = jsonValue.isObject()) != null)
			{
				returnValue = jsonObject.keySet();
			}
		}
		return returnValue;
	}

	public static String getValue(Widget widget)
	{
		String value = null;
		if (widget instanceof TextBox) {
			TextBox tb = (TextBox)widget;
			value = tb.getText();
		}
		else if (widget instanceof TextArea) {
			TextArea ta = (TextArea)widget;
			value = ta.getText();
		}
		else if (widget instanceof ListBox) {
			ListBox lb = (ListBox)widget;
			if (lb.isMultipleSelect()) {
				value = "";
				int cnt = lb.getItemCount();
				for (int i=0; i<cnt; i++) {
					if (lb.isItemSelected(i)) {
						String valuei = null;
						try {
							valuei = lb.getValue(i);
						} catch (Exception e){valuei = null;}
						if (valuei != null) value += valuei + ",";
					}					
				}
				if (value.length() > 0) {
					int lngth = value.length() -1;
					value = value.substring(0,lngth);
				}
			}
			else {
				int index = lb.getSelectedIndex();
				try {
					value = lb.getValue(index);
				} catch (Exception e){value = "";}
			}
		}
		else if (widget instanceof DateBox) {
			DateBox db = (DateBox)widget;
			Date date = db.getValue();
			value = "";
			if (date != null) value = String.valueOf(db.getValue().getTime());
		}
		else if (widget instanceof FileUpload) {
			FileUpload fu = (FileUpload)widget;
			value = fu.getName();
		}
		else if (widget instanceof Hidden) {
			Hidden hd = (Hidden)widget;
			value = hd.getValue();
		}
		else if (widget instanceof Label) {
			Label hd = (Label)widget;
			value = hd.getText();
		}
		else if (widget instanceof CheckBox) {
			CheckBox cb = (CheckBox)widget;
			value = "0";
			if (cb.getValue()) value = "1";
		}
		return value;
	}
	
	/**
	 * Used to create a string that is a warning about minimum length of input value
	 * @param constants
	 * @param buffer
	 * @param textbox
	 * @param label
	 * @param minLength
	 * @return
	 */
	public static StringBuffer lengthWarning(GWTCommerceCommonConstants constants, 
			StringBuffer buffer, TextBox textbox, String label, int minLength)
	{
		return lengthWarning(constants, buffer, textbox.getText(), label, minLength);
	}
	
	public static StringBuffer lengthWarning(GWTCommerceCommonConstants constants, 
			StringBuffer buffer, String text, String label, int minLength)
	{
		if (text.length() < minLength)
		{
			if (buffer.length() > 0) buffer.append("\n");
			buffer.append(label).append(constants.LengthWarningCharactersStart()).append(" ");
			buffer.append(minLength).append(" ").append(constants.LengthWarningCharactersEnd());
		}
		return buffer;
	}


	public static String lengthWarning(GWTCommerceCommonConstants constants, String label, int minLength)
	{
		StringBuffer buffer = new StringBuffer();
		buffer.append(label).append(constants.LengthWarningCharactersStart()).append(" ");
		buffer.append(minLength).append(" ").append(constants.LengthWarningCharactersEnd());
		return buffer.toString();
	}
}
